home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / qbfe10.arc / EDITFLD.BAS next >
BASIC Source File  |  1987-11-27  |  20KB  |  389 lines

  1. '                              EditField
  2. '
  3. '                                V1.0
  4. '
  5. '                     (C) 1987 By Tony Elliott
  6. '
  7. '            A Multi-purpose Field Editor for QuickBASIC V4.0
  8. '
  9. '        Please refer any comments or suggestions to the QuickBASIC
  10. '      Conference at Programmer's Information Exchange (404) 928-0033
  11. '
  12. '
  13. '
  14. 'EDITFLD.BAS  Module Level Code
  15.  
  16. DEFINT A-Z
  17. COMMON SHARED /editfld/ row, col, ucase, minval!, maxval!, justify, padchar, keystat, kfg, kbg, krow, kcol, sfg, sbg, dfg, dbg, insmode, nul, Alarm
  18.  
  19. SUB EditField (old$, ed$, format$, retflag%) STATIC
  20.  
  21. Initialize:
  22.     retflag = 0                                     'Reset condition flag from previous calls
  23.     ed$ = old$                                      'Make old$ the string to edit
  24.     comp$ = old$                                    'Keep an original copy (before case conversions)
  25.     fldlen = LEN(format$)                           'Set fldlen to the length of format$.
  26.     IF insmode <> 0 THEN                            'If insert mode is on then
  27.         insert = -1                                 'change value for call to setkbd.
  28.         LOCATE , , , 1, 7                           'Change cursor to block
  29.     ELSE                                            'If insert is off then
  30.         insert = 0                                  'change variable for call
  31.         LOCATE , , , 6, 7                           'and change cursor to flat line.
  32.     END IF
  33.     CALL setkbd(insert, 0, 0, 0)                    'Set insert mode.
  34.  
  35.                                                            'Set Defaults
  36.     IF row = 0 AND col = 0 THEN row = CSRLIN: col = POS(0) 'Use current cursor location.
  37.     IF sfg = 0 AND sbg = 0 THEN sfg = 0: sbg = 7           'and background colors.
  38.     IF dfg = 0 AND dbg = 0 THEN dfg = 7: dbg = 0           'when exiting the routine.
  39.     IF padchar = 0 THEN padchar = 32
  40.     IF (krow = 0 AND kcol = 0) OR (kfg = 0 AND kbg = 0) THEN keystat = 0  'For keystat, turn it off.
  41.  
  42.     GOSUB ChangeCase                                'Makes initial case conversion / UPCASE flag
  43.     fieldreset = 0                                  'Use sfg,sbg colors
  44.     IF LEFT$(format$, 1) = "\" THEN                 'Checks the type of data to be
  45.         ftype = 1                                   'input.
  46.     END IF
  47.                                                     'If ftype=1 then it is a text field
  48.     IF LEFT$(format$, 1) = "#" THEN                 'If ftype=2 then it is a numeric field
  49.         ftype = 2
  50.         IF ucase <> 0 THEN insert = -1
  51.         IF VAL(old$) = 0 THEN                       'Make sure that no string data was
  52.             old$ = ""                               'accidently passed in old$
  53.             comp$ = ""
  54.         ELSE
  55.             old$ = STR$(VAL(old$))                  'If numeric mode, make sure a numeric
  56.             comp$ = old$                            'VALUE (not alphabetic characters)
  57.         END IF                                      'was passed in old$.
  58.         IF maxval! = 0 THEN                         'If no value was supplied for maxval!,
  59.             decloc = INSTR(format$, ".")            'find the location of the decimal.
  60.             IF decloc = 0 THEN                      'If no decimal, then set maxval! to
  61.                 maxval! = 10 ^ LEN(format$) - 1     '10 to the power of the number of digits
  62.             ELSE                                    'in format$ minus 1, or if there is a decimal,
  63.                 maxval! = 10 ^ (decloc - 1) - 1     'to the power of the number of digits to the
  64.             END IF                                  'left of the decimal minus 1.
  65.         END IF
  66.     END IF
  67.  
  68.     IF ftype = 0 THEN                               'If format$ was invalid
  69.         stat$ = "** Invalid FORMAT$ !  Cannot Process field! **"
  70.         CALL StatLine(stat$, stat)                  'Display stat$ on line 25
  71.         GOSUB Alarm                                 'Sound alarm
  72.         retflag = 99                                'Set flag to indicate error.
  73.         GOSUB ResetVar                              'Reset argument variables
  74.         EXIT SUB                                    'Exit subprogram
  75.     END IF
  76.     GOSUB FormatField                               'Display field in required format.
  77.  
  78. Position:
  79.     GOSUB DisplayField                              'Display field contents in selected colors
  80.                                                     'and format.
  81. Strobe:
  82.     inp$ = INKEY$                                   'Strobe keyboard for input
  83.     GOSUB DisplayStatus                             'display INS, CAPS & NUM Lock status
  84.     IF inp$ = "" THEN GOTO Strobe                   'Nothing here, try again.
  85.  
  86.     IF stat = 1 THEN                                'If there is a message on the status
  87.         CALL StatLine("", stat)                     'line... turn it off.
  88.     END IF
  89.  
  90.     IF LEN(inp$) = 2 THEN GOTO ExtendedKeys         'Check to see if extended key was pressed
  91.  
  92.     char = ASC(inp$)                                'It's easier to work with numbers using CASE.
  93.     SELECT CASE char                                'Checks for standard characters
  94.         CASE 13                                     'Check for return.
  95.             GOTO ExitSub
  96.  
  97.         CASE 27                                     'check for ESC key.  If pressed once and
  98.             IF ftype = 1 THEN                       'the field has been changed from its
  99.                 IF comp$ <> ed$ AND abort = 0 THEN  'original value, the original value will
  100.                     ed$ = old$                      'be restored.  If pressed a second time,
  101.                     curpos = LEN(ed$): abort = -1   'the routine will be exited and an abort
  102.                     GOTO Position                   'flag will be set.
  103.                 ELSE
  104.                     retflag = 1                     'Set retflag to indicating an abort,
  105.                     GOSUB FormatField               'Reset the field display,
  106.                     GOSUB ResetVar                  'reset argument variables and
  107.                     EXIT SUB                        'exit the routine.
  108.                 END IF
  109.             ELSE
  110.                 firstnum = 0
  111.                 IF VAL(old$) <> VAL(ed$) THEN       'This handles "numeric only" data if the
  112.                     IF VAL(old$) > 0 THEN           'ESC was pressed
  113.                         ed$ = old$                  'Restore original value
  114.                         GOSUB FormatField           'Use special numeric formatting.
  115.                         GOTO Position               'Go back and display field.
  116.                     ELSE
  117.                         LOCATE row, col             'If nothing was passed in old$,
  118.                         PRINT SPC(fldlen);          'and no current value, erase the
  119.                         GOTO Position               'field.
  120.                     END IF
  121.                 ELSE
  122.                     retflag = 1                     'ESC was pressed a second consecutive
  123.                     GOSUB FormatField               'time. Set retflag to indicate an "abort",
  124.                     GOSUB ResetVar                  'reset argument variables
  125.                     EXIT SUB                        'and exit the routine.
  126.                 END IF
  127.             END IF
  128.  
  129.         CASE 8                                      'Check for backspace key.
  130.             IF LEN(ed$) = 0 OR curpos = 0 THEN      'If on an empty field...
  131.                 GOSUB Alarm                         'sound alarm and go back for
  132.                 GOTO Strobe                         'more input.
  133.             END IF
  134.             IF LEN(ed$) > 1 THEN                    'If ed$ is longer than one character then
  135.             ed$ = LEFT$(ed$, curpos - 1) + RIGHT$(ed$, LEN(ed$) - (curpos))
  136.                 curpos = curpos - 1                 'Move cursor to left one character.
  137.             ELSE
  138.                 ed$ = ""                            'If ed$ is one character long then
  139.                 curpos = 0                          'erase it and reset the cursor position.
  140.             END IF
  141.  
  142.         CASE ELSE                                   'If any other key was pressed
  143.         IF ftype = 1 THEN                           'and in the text entry mode, check
  144.             IF ASC(inp$) < 32 OR ASC(inp$) > 128 THEN 'if character is standard alphabetic.
  145.                 GOSUB Alarm                         'Nope! Sound bell and display a message
  146.                 stat$ = "** Invalid Character! **"  'on line 25.
  147.                 CALL StatLine(stat$, stat)
  148.                 GOTO Strobe                         'Go back and try again
  149.             ELSE
  150.                 GOSUB ChangeCase                    'Character passed test.. Now make the
  151.             END IF                                  'proper case conversion.
  152.         ELSE
  153.             IF ASC(inp$) <> 46 AND (ASC(inp$) < 48 OR ASC(inp$) > 57) THEN                           '0-9 and "." (decimal).
  154.                 GOSUB Alarm                                 'Uh oh.. Gotcha
  155.                 stat$ = "Only Numeric Input is Allowed!"    'Sound the bell and display the
  156.                 CALL StatLine(stat$, stat)          'status message on line 25.
  157.                 GOTO Strobe                         'Go back and try again.
  158.             END IF
  159.             IF ucase <> 0 AND firstnum = 0 THEN     'If in the numeric mode and ucase
  160.                 ed$ = inp$                          'is non-zero and a key has not been
  161.                 firstnum = 1                        'pressed since the routine has been
  162.                 curpos = 1                          'called, clear the field, set ed$ to
  163.                 GOSUB DisplayField                  'the key pressed, set the cursor to the
  164.                 GOTO Strobe                         'begin
  165.             END IF
  166.         END IF
  167.  
  168.         IF LEN(ed$) = fldlen AND (insert OR curpos = fldlen) THEN 'Is the field at its maximum
  169.             GOSUB Alarm                                         'length? Yes, sound bell
  170.             stat$ = "** String is at Maximum Length! **"        'display status message
  171.             CALL StatLine(stat$, stat)
  172.             GOTO Strobe                             'Go back and try again
  173.         END IF
  174.  
  175.         IF insert THEN                              'In the insert mode, add inp$ at cursor position moving
  176.             ed$ = LEFT$(ed$, curpos) + inp$ + RIGHT$(ed$, LEN(ed$) - (curpos)) 'everthing to the right of the cursor
  177.         ELSE                                        'to the right one space.
  178.             IF curpos = LEN(ed$) THEN               'If at the end of the field and in the
  179.                 ed$ = ed$ + inp$                    'overwrite mode, add inp$ to the end of
  180.             ELSE                                    'ed$.
  181.                 MID$(ed$, curpos + 1) = inp$        'If not at the end of the field, replace
  182.             END IF                                  'character at the cursor's position with
  183.         END IF                                      'inp$.
  184.         curpos = curpos + 1                         'Move over one space.
  185.         IF curpos = fldlen THEN                     'If cursor is past the end of the field
  186.             curpos = fldlen - 1                     'move it back.
  187.         END IF
  188.     END SELECT
  189.     abort = 0                                       'Reset the ESC flag
  190.     GOTO Position
  191.  
  192.  
  193. ExtendedKeys:                                       'Process the Extended Keys
  194.     exkey = ASC(RIGHT$(inp$, 1))                    'Put extended key code in exkey.
  195.     SELECT CASE exkey
  196.         CASE 83                                     'Delete Key -- Deletes character at
  197.             IF curpos < LEN(ed$) THEN               'cursor position.
  198.                 ed$ = LEFT$(ed$, curpos) + RIGHT$(ed$, LEN(ed$) - (curpos + 1))
  199.             ELSE                                    'If cursor is not inside the field
  200.                 GOSUB Alarm                         'then sound bell.
  201.             END IF
  202.  
  203.         CASE 75                                     'Left Arrow -- Cursor left one
  204.             curpos = curpos - 1                     'character. Stop at first character
  205.             IF curpos < 0 THEN curpos = 0           'in field
  206.  
  207.         CASE 77                                     'Cursor-Right
  208.             IF curpos < LEN(ed$) AND curpos < fldlen - 1 THEN  'Don't move past the right end of the
  209.                 curpos = curpos + 1                 'current string or outside of the defined field
  210.             END IF
  211.  
  212.         CASE 82                                     'Insert Key.  Acutal changing of the
  213.             IF insert THEN                          'If insert is on
  214.                 LOCATE , , , 1, 7                   'change cursor to a block.
  215.             ELSE                                    'if not,
  216.                 LOCATE , , , 6, 7                   'change it to a flat line
  217.             END IF
  218.  
  219.         CASE 71                                     'Home Key -- Position cursor on
  220.             curpos = 0                              'first character in field.
  221.  
  222.         CASE 79                                     'End Key -- Cursor to last
  223.              curpos = LEN(ed$)                      'character in field.
  224.              IF curpos = fldlen THEN                'Don't let cursor go ouside
  225.                 curpos = fldlen - 1                 'of the field
  226.              END IF
  227.  
  228.         CASE 119                                    'Ctrl-Home -- Deletes contents of
  229.             ed$ = ""                                'current field.
  230.             curpos = 0
  231.  
  232.         CASE 116                                    'Ctrl-Cursor Right - Move cursor to the
  233.             wordloc = INSTR(curpos + 1, ed$, " ")   'right one word.
  234.             IF wordloc > 0 THEN curpos = wordloc    'Space is the only valid delimeter.
  235.  
  236.         CASE 115                                    'Ctrl-Left Arrow - Word Left.
  237.             FOR char = curpos TO 1 STEP -1          'Start looking for a space from the current
  238.                 word$ = MID$(ed$, char, 1)          'cursor position to the beginning of the field.
  239.                 IF word$ = " " AND char < curpos THEN 'If found, the position is flagged in the
  240.                     EXIT FOR                        '"char" variable.  Exit the FOR loop.
  241.                 END IF                              'If not found, try the next character.
  242.             NEXT char                               'Position cursor at flagged location.  If nothing
  243.             curpos = char                           'was found, it will be at the beginning of the field.
  244.  
  245.         CASE 117                                    'Cntrl-End -Clear from cursor to end of field
  246.             ed$ = LEFT$(ed$, curpos)                'Left trunctuate ed$ at cursor position
  247.             GOSUB DisplayField                      'Redisplay field
  248.  
  249.         CASE ELSE                                   'If any other extended key was pressed,
  250.             retflag = exkey                         'return its code in retflag.
  251.             GOTO ExitSub                            'This is signal to exit the routine.
  252.  
  253.      END SELECT
  254.      GOTO Position
  255.  
  256.  
  257. ExitSub:
  258.     IF nul <> 0 AND ((ftype = 1 AND ed$ = "") OR (ftype = 2 AND VAL(ed$) = 0)) THEN
  259.         stat$ = "*** An Entry is Required.  Press ESC to Abort ***"
  260.         CALL StatLine(stat$, stat)                  'If ed$ is nul and it is not allowed,
  261.         GOSUB Alarm                                 'display a message, sound the bell and
  262.         GOTO Position                               'return for input.
  263.     END IF
  264.  
  265.     IF ftype = 2 THEN
  266.         IF (VAL(ed$) > maxval! OR VAL(ed$) < minval!) THEN
  267.             stat$ = "*** Acceptable Values are" + STR$(minval!) + " -" + STR$(maxval!) + ". Please Re-enter. ***"
  268.             CALL StatLine(stat$, stat)              'If value of ed$<minval! or >maxval! then
  269.             GOSUB Alarm                             'sound the bell..
  270.             ed$ = old$                              'restore ed$ to the original value
  271.             GOSUB FormatField                       'Re-display the original value in the
  272.             GOTO Position                           'correct format and begin again.
  273.         END IF
  274.     END IF
  275.     fieldreset = 1                                  'Display field using dfg,dbg colors.
  276.     GOSUB FormatField                               'Retrieve the formatted output.
  277.     IF ftype = 1 THEN                               'If in the text entry mode, format the text
  278.         SELECT CASE justify                         'obeying the justify argument.
  279.             CASE 1                                  'Left Justify
  280.                 ed$ = LEFT$(ed$ + STRING$(fldlen, 32), fldlen)
  281.  
  282.             CASE 2                                  'Right justify
  283.                 ed$ = RIGHT$(STRING$(fldlen, 32) + ed$, fldlen)
  284.  
  285.             CASE 3                                    'Center text within the width of
  286.                 IF LEN(ed$) < fldlen - 2 THEN         'format$.  Length must be at
  287.                     temp$ = STRING$(fldlen, 32)       'least 2 characters less than
  288.                     fldpos = (fldlen - LEN(ed$)) / 2  'format$.
  289.                     MID$(temp$, fldpos, LEN(ed$)) = ed$
  290.                     ed$ = temp$
  291.                 END IF
  292.  
  293.             CASE ELSE                               'If zero or anything else, do nothing.
  294.          END SELECT
  295.          GOSUB FormatField                          'Re-display the formatted field
  296.     ELSE
  297.         IF justify <> 0 THEN                        'If in the numeric mode an justify is
  298.             ed$ = STR$(VAL(ed$))                    'set to a non-zero, remove the
  299.         END IF                                      'print using format from ed$.
  300.     END IF
  301.     GOSUB ResetVar                                  'Reset argument variables
  302.     EXIT SUB                                        'Bye-bye
  303.  
  304. DisplayField:
  305.     GOSUB ChangeCase                                'Make case conversion.
  306.     COLOR sfg, sbg                                  'Use "selected" colors
  307.     LOCATE row, col, 0                              'Position cursor
  308.     IF ftype = 1 THEN                               'Text print routine
  309.         PRINT USING format$; ed$ + STRING$(fldlen, padchar);
  310.         LOCATE row, col + LEN(ed$)
  311.     ELSE
  312.         PRINT LEFT$(ed$ + STRING$(fldlen, 32), fldlen)'Numeric print routine
  313.     END IF
  314.     LOCATE row, col + curpos, 1
  315. RETURN
  316.  
  317. FormatField:
  318.     num$ = ""
  319.     LOCATE row, col, 0                              'Position cursor & turn off
  320.     GOSUB ChangeCase                                'Change to proper case
  321.      IF fieldreset = 1 OR retflag = 1 THEN          'Set color based on FIELDRESET.
  322.         COLOR dfg, dbg                              'IF 1 then the routine is preparing
  323.      ELSE                                           'exit, and if 0 the routine is
  324.         COLOR sfg, sbg                              'initializing.
  325.      END IF
  326.      IF ftype = 1 THEN                              'Display text using format$
  327.         PRINT USING format$; ed$
  328.      ELSE
  329.         IF VAL(ed$) = 0 THEN                        'If ed$ has no numeric value then just
  330.             PRINT SPC(fldlen);                      'print spaces on the screen so entering
  331.             num$ = " "                              'new data is easier.
  332.         ELSE
  333.             PRINT USING format$; VAL(ed$)           'Print numeric data using format$.
  334.             IF num$ = "" THEN
  335.                 FOR char = col TO col + fldlen - 1  'Read formated numeric display
  336.                     num$ = num$ + CHR$(SCREEN(row, char)) 'from screen into num$ for proper
  337.                 NEXT char                           'on screen editing
  338.                 ed$ = num$                          'Assign ed$ with data retrieved from
  339.             END IF                                  'display.
  340.         END IF
  341.      END IF
  342.      IF insmode THEN                                'If insert is on, position cursor at beginning
  343.         curpos = 0                                  'of field.  If off, position cursor at end
  344.      ELSE                                           'of field (personal preference).
  345.         curpos = LEN(ed$)
  346.         IF curpos = fldlen THEN                     'Don't let cursor wander outside
  347.             curpos = fldlen - 1                     'of the field
  348.         END IF
  349.      END IF
  350.      LOCATE , , 1                                   'Make sure cursor is on.
  351. RETURN
  352.  
  353. ChangeCase:
  354.     IF ucase = 1 THEN                               'Convert to upper case
  355.         ed$ = UCASE$(ed$)
  356.         inp$ = UCASE$(inp$)
  357.         comp$ = UCASE$(comp$)
  358.     ELSEIF ucase = 2 THEN                           'Convert to lower case
  359.         ed$ = LCASE$(ed$)
  360.         inp$ = LCASE$(inp$)
  361.         comp$ = LCASE$(comp$)
  362.     END IF
  363. RETURN
  364.  
  365. DisplayStatus:
  366.     kstat$ = ""                                         'Nul the Keyboard status $
  367.     CALL GetKbd(insert, caps, numlk, scrl)              'Get keyboard status.
  368.     IF keystat = 0 THEN RETURN                          'If keystat is off, return
  369.     IF insert THEN kstat$ = "INS" ELSE kstat$ = "OVW"   'Create the key status display.
  370.     IF caps THEN kstat$ = kstat$ + "CAP" ELSE kstat$ = kstat$ + "   "
  371.     IF numlk THEN kstat$ = kstat$ + "NUM" ELSE kstat$ = kstat$ + "   "
  372.     CALL CalcAttr(kfg, kbg, attr)                       'Calculate the color attribute. (ADVBAS or PROBAS)
  373.     CALL XqPrint(kstat$, krow, kcol, attr, 0)           'Display it. (ADVBAS)
  374.    'CALL XqPrint(kstat$, krow, kcol, attr, 0, 0)        'Display it (PROBAS)
  375. RETURN
  376.  
  377. ResetVar:
  378.     row = 0: col = 0                                    'Reset variables for routine
  379. RETURN                                                  'exit.
  380.  
  381. Alarm:                                              
  382.     IF noise = 0 THEN                                   'Sound of error alarm .. Change to
  383.         BEEP                                            'SOUND 1000,1:SOUND 1500,1:SOUND 1000,1
  384.     END IF                                              'if you don't like the regular ole "BEEP"
  385. RETURN
  386.  
  387. END SUB
  388.  
  389.